package com.snail.wms.base.business.attr.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.snail.common.core.constant.CommonConstants;
import com.snail.common.core.exception.ServiceException;
import com.snail.common.core.utils.PageUtils;
import com.snail.common.core.utils.StringUtils;
import com.snail.common.core.utils.ValidationUtils;
import com.snail.common.core.utils.bean.BeanUtils;
import com.snail.common.core.web.page.PageResult;
import com.snail.system.api.dto.SysUserDto;
import com.snail.wms.base.business.attr.domain.BaseAttrValue;
import com.snail.wms.base.business.attr.domain.BaseAttr;
import com.snail.wms.base.business.attr.dto.BaseAttrDto;
import com.snail.wms.base.business.attr.mapper.BaseAttrMapper;
import com.snail.wms.base.business.attr.query.BaseAttrQuery;
import com.snail.wms.base.business.attr.service.IBaseAttrService;
import com.snail.wms.base.business.attr.service.IBaseAttrValueService;
import com.snail.wms.base.business.category.domain.BaseCategory;
import com.snail.wms.base.business.category.service.IBaseCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Validator;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 属性Service业务层处理
 * @Author: snail
 * @CreateDate: 2024-05-26
 * @Version: V1.0
 */
@Service
public class BaseAttrServiceImpl extends ServiceImpl<BaseAttrMapper, BaseAttr> implements IBaseAttrService {

    @Autowired
    private IBaseAttrValueService baseAttrValueService;
    @Autowired
    private IBaseCategoryService baseCategoryService;
    @Autowired
    protected Validator validator;

    @Override
    public PageResult<BaseAttrDto> selectBaseAttrPage(BaseAttrQuery query) {
        Page<BaseAttrDto> page = PageUtils.buildPage(query);
        page = this.baseMapper.selectBaseAttrPage(page, query);
        return PageUtils.pageResult(page);
    }

    @Override
    public BaseAttrDto getBaseAttrById(String attrId) {
        BaseAttrDto dto = new BaseAttrDto();
        BaseAttr attr = getById(attrId);
        BeanUtils.copyProperties(attr, dto);
        List<BaseAttrValue> values = baseAttrValueService.getBaseAttrValueByAttrId(attrId);
        dto.setAttrValues(values.stream().map(BaseAttrValue::getAttrValue).collect(Collectors.toList()));
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String insertBaseAttr(BaseAttrDto attrDto) {
        if (isExistsAttrName(attrDto.getAttrName())) {
            throw new ServiceException("属性名[" + attrDto.getAttrName() + "]已存在!");
        }
        BaseAttr baseAttr = new BaseAttr();
        BeanUtils.copyProperties(attrDto, baseAttr);
        save(baseAttr);

        List<String> attrValues = attrDto.getAttrValues();
        List<BaseAttrValue> valueList = attrValues.stream()
                .map(item -> {
                    BaseAttrValue value = new BaseAttrValue();
                    value.setAttrId(baseAttr.getAttrId());
                    value.setAttrValue(item);
                    value.setStatus(baseAttr.getStatus());
                    return value;
                }).collect(Collectors.toList());
        baseAttrValueService.saveBatch(valueList);
        return baseAttr.getAttrId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateBaseAttr(BaseAttrDto attrDto) {
        BaseAttr baseAttr = new BaseAttr();
        baseAttr.setAttrId(attrDto.getAttrId());
        baseAttr.setAttrName(attrDto.getAttrName());
        baseAttr.setStatus(attrDto.getStatus());
        baseAttr.setCategoryId(attrDto.getCategoryId());
        baseAttr.setCategoryCode(attrDto.getCategoryCode());
        baseAttr.setCategoryName(attrDto.getCategoryName());
        baseAttr.setCategoryFullName(attrDto.getCategoryFullName());
        //先删再插入
        baseAttrValueService.deleteValuesByAttrId(baseAttr.getAttrId());
        List<BaseAttrValue> valueList = attrDto.getAttrValues().stream()
                .map(item -> {
                    BaseAttrValue value = new BaseAttrValue();
                    value.setAttrId(baseAttr.getAttrId());
                    value.setAttrValue(item);
                    value.setStatus(baseAttr.getStatus());
                    return value;
                }).collect(Collectors.toList());
        baseAttrValueService.saveBatch(valueList);
        return updateById(baseAttr);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBaseAttrByIds(String[] attrIds) {
        int batch = baseMapper.deleteBatchIds(Arrays.asList(attrIds));
        return batch == attrIds.length;
    }

    @Override
    public List<BaseAttrDto> selectBaseAttrList(BaseAttrQuery query) {
        return baseMapper.selectBaseAttrList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStatus(BaseAttr baseAttr) {
        LambdaUpdateWrapper<BaseAttr> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(BaseAttr::getStatus, baseAttr.getStatus());
        updateWrapper.eq(BaseAttr::getAttrId, baseAttr.getAttrId());
        return this.update(updateWrapper);
    }

    @Override
    public String checkExcelData(BaseAttrDto attrDto) {
        StringBuffer error = new StringBuffer();
        ValidationUtils.checkProperty(validator, attrDto, Arrays.asList("categoryId", "status"), SysUserDto.class, error);
        if (StringUtils.isNotEmpty(error)) {
            return error.toString();
        }
        if (isExistsAttrName(attrDto.getAttrName())) {
            error.append("属性名[").append(attrDto.getAttrName()).append("]已存在!");
        }
        BaseCategory category = baseCategoryService.getBaseCategoryByCode(attrDto.getCategoryCode());
        if (category == null) {
            error.append("分类编码[").append(attrDto.getCategoryCode()).append("]不存在!");
        } else {
            attrDto.setCategoryId(category.getCategoryId());
            attrDto.setCategoryName(category.getCategoryName());
            attrDto.setCategoryCode(category.getCategoryCode());
            attrDto.setCategoryFullName(category.getCategoryFullName());
        }
        return null;
    }

    /**
     * 属性名称是否存在
     *
     * @return 结果
     */
    private boolean isExistsAttrName(String attrName) {
        LambdaQueryWrapper<BaseAttr> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseAttr::getAttrName, attrName);
        return baseMapper.selectCount(queryWrapper) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveExcelData(List<BaseAttrDto> dataList) {
        List<BaseAttr> attrs = new ArrayList<>();
        List<BaseAttrValue> attrValues = new ArrayList<>();
        for (BaseAttrDto dto : dataList) {
            BaseAttr attr = new BaseAttr();
            BeanUtils.copyProperties(dto, attr);
            attr.setStatus(CommonConstants.STATUS_ENABLE);
            String id = IdWorker.get32UUID();
            attr.setAttrId(id);
            attrs.add(attr);

            List<BaseAttrValue> collect = dto.getAttrValues().stream().map(item -> {
                BaseAttrValue value = new BaseAttrValue();
                value.setAttrId(id);
                value.setAttrValue(item);
                value.setStatus(attr.getStatus());
                return value;
            }).collect(Collectors.toList());
            attrValues.addAll(collect);
        }
        if (CollUtil.isNotEmpty(attrs)) {
            this.saveBatch(attrs);
        }
        if (CollUtil.isNotEmpty(attrValues)) {
            this.baseAttrValueService.saveBatch(attrValues);
        }
    }
}
